package com.youlu.campus.service.douyin;

import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.douyin.dto.DouYinAccessTokenDTO;
import com.youlu.campus.entity.douyin.dto.DouYinResult;
import com.youlu.campus.entity.douyin.dto.DouYinSessionDTO;
import com.youlu.campus.entity.douyin.dto.UserLoginDTO;
import com.youlu.campus.service.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : [dengbo]
 * @className : DouYinApiService
 * @description : [抖音api]
 * @createTime : [2023/2/28 14:33]
 */
@Service
@Slf4j
public class DouYinApiService {

    @Value("${spring.profiles.active}")
    private String active;

    private static final String MINI_LOGIN_PROD_URL = "https://developer.toutiao.com/api/apps/v2/jscode2session";
    private static final String MINI_LOGIN_TEST_URL = "https://open-sandbox.douyin.com/api/apps/v2/jscode2session";
    private static final String ACCESS_TOKEN_TEST_URL = "https://open-sandbox.douyin.com/api/apps/v2/token";
    private static final String ACCESS_TOKEN_PROD_URL = "https://developer.toutiao.com/api/apps/v2/token";
    /**
     * 线上环境-二维码接口
     */
    private final static String QR_CODE_PROD = "https://developer.toutiao.com/api/apps/qrcode";
    /**
     * 沙盒地址-二维码接口
     */
    private final static String QR_CODE_SAND_BOX = "https://open-sandbox.douyin.com/api/apps/qrcode";

    public String APP_ID = "tt455f33e2da60b56101";
    private String APP_SECRET = "0281aec8011d565da062ca33b8818a1e2b5c5fcd";

    @Autowired
    private ThirdTokenStoreService thirdTokenStoreService;

    public DouYinSessionDTO getSessionKeyInfo(UserLoginDTO dto) {
        dto.setAppId(APP_ID);
        dto.setAppSecret(APP_SECRET);
        String url = "prod".equals(active) ? MINI_LOGIN_PROD_URL : MINI_LOGIN_TEST_URL;
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("appid", dto.getAppId());
            param.put("secret", dto.getAppSecret());
            if (StringUtils.isNotBlank(dto.getCode())) {
                param.put("code", dto.getCode());
            }
            if (StringUtils.isNotBlank(dto.getAnonymousCode())) {
                param.put("anonymousCode", dto.getAnonymousCode());
            }
            String str = HttpClientUtils.getRestTemplate().postForObject(url, param, String.class);
            if (StringUtils.isBlank(str)) {
                log.error(":>>> HTTP content为空");
                throw new BusinessException("返回信息为空");
            }
            TypeReference<DouYinResult<DouYinSessionDTO>> typeReference = new TypeReference<DouYinResult<DouYinSessionDTO>>() {
            };
            DouYinResult<DouYinSessionDTO> result = JSON.parseObject(str, typeReference);
            log.info("dou yin login result:{}", result);
            if (result.getErrNo() == 0) {
                return result.getData();
            }
        } catch (Exception e) {
            log.error("dou yin login error", e);
        }
        return null;
    }

    public String getAccessToken(String appId) {
        String accessToken = thirdTokenStoreService.getAccessToken(appId);
        if (StringUtils.isBlank(accessToken)) {
            log.info("dou yin token is null remake");
            DouYinAccessTokenDTO accessTokenDTO = reGetAccessToken(appId);
            return accessTokenDTO.getAccessToken();
        }
        return accessToken;
    }

    public DouYinAccessTokenDTO reGetAccessToken(String appId) {
        DouYinAccessTokenDTO accessTokenDTO = getAccessToken(APP_ID, APP_SECRET);
        if (accessTokenDTO == null) {
            throw new BusinessException("生成token失败");
        }
        thirdTokenStoreService.setAccessToken(appId, accessTokenDTO.getAccessToken(), 6000);
        return accessTokenDTO;
    }

    public DouYinAccessTokenDTO getAccessToken(String appId, String appSecret) {
        String url = ACCESS_TOKEN_PROD_URL;
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("appid", appId);
            param.put("secret", appSecret);
            param.put("grant_type", "client_credential");
            String str = HttpClientUtils.getRestTemplate().postForObject(url, param, String.class);
            if (StringUtils.isBlank(str)) {
                log.error(":>>> HTTP content为空");
                throw new BusinessException("返回信息为空");
            }
            TypeReference<DouYinResult<DouYinAccessTokenDTO>> typeReference = new TypeReference<DouYinResult<DouYinAccessTokenDTO>>() {
            };
            DouYinResult<DouYinAccessTokenDTO> result = JSON.parseObject(str, typeReference);
            log.info("dou yin login result:{}", result);
            if (result.getErrNo() == 0) {
                return result.getData();
            }
        } catch (Exception e) {
            log.error("dou yin login error", e);
        }
        return null;
    }

    public byte[] getQrcodeBytes(String accessToken, String path, String appName) {
        String url = QR_CODE_PROD;
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        paramMap.put("appname", appName);
        paramMap.put("path", URLUtil.encode(path));
        paramMap.put("width", 430);
        Map<String, Integer> color = new HashMap<>(3);
        color.put("r", 0);
        color.put("g", 0);
        color.put("b", 0);
        paramMap.put("line_color", color);
        log.info("抖音二维码请求入参数:{}",JSON.toJSONString(paramMap));
        byte[] imageBytes = HttpClientUtils.getRestTemplate().postForObject(url, paramMap, byte[].class);
        if (imageBytes == null) {
            throw new BusinessException("抖音二维码信息为空");
        }
        long length = imageBytes.length;
        if (length < 1000) {
            String str = getByteToStr(imageBytes);
            JSONObject object = JSON.parseObject(str);
            if (object != null && object.getInteger("errcode") != 0) {
                String errorMsg = object.getString("errmsg");
                throw new BusinessException(StringUtils.isBlank(errorMsg) ? "生成抖音二维码失败" : errorMsg);
            }
        }
        return imageBytes;
    }

    public static String getByteToStr(byte[] bytes) {
        try {
            return new String(bytes, "utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error("byte to str error", e);
        }
        return null;
    }
}
